<?php

class Rapide_Controller_Front_Plugin_ACL extends Rapide_Controller_Front_Plugin
{
	public function preExecution(Rapide_Dispatcher_Token_Interface $oToken)
	{
		if(!$this->isDispatchable($oToken)) {
			return $oToken;
		}

		$sController = $oToken->getController();
		$sAction = $oToken->getAction();

		$sControllerClass = 'Controller_' . ucfirst($sController);
		$oController = new $sControllerClass;

		$oControllerCfg = $oController->getConfig();

		if(is_null($oControllerCfg)) {
			return $oToken;
		}
		
		// Load configuration with error actions

		$oConfig = new Rapide_Config;
		$oConfig->load('Controller.php');

		// If action has been disabled return default action
	 
		if($oControllerCfg->has('actions', strtolower($sAction), 'disabled')) {
			$oToken = new Rapide_Dispatcher_Token($oConfig->get('Controller', 'default', 'controller'), $oConfig->get('Controller', 'default', 'action'));

			return $oToken;
		}

		/**
		 *	If security section in configuration has not been defined,
		 *	leave the plugin.
		 */

		if(!$oControllerCfg->has('actions', $sAction, 'security'))
			return $oToken;

		/**
		 * Initialize Rapide_ACL
		 */
		$oACL = Rapide_Controller_Front::getInstance()->getACL();

		/**
		 * Initialize Rapide_ACL_Loader and get primary role
		 */	 
		$oAclLoader = new Rapide_ACL_Loader;
		$oConfig->load('ACL.php');

		/**
		 * Set primary role and primary rules for anonymous user
		 */
		$oAclLoader->setOptions($oConfig->get('ACL', 'primary_role')->getArray(), $oConfig->get('ACL', 'primary_rules')->getArray());

		$oAclLoader->loadRules($oACL);

		/**
		 *	Add allow groups to Rapide_ACL.
		 */
		if($oControllerCfg->has('actions', $sAction, 'security', 'resources')) {
			$aResourcesAllow = $oControllerCfg->get('actions', $sAction, 'security', 'resources')->getArray();

			if(!is_array($aResourcesAllow)) {
				$sError = sprintf('Resources list for action %s in controller %s must be an array', $sAction, $sController);

				throw new Rapide_Controller_Front_Plugin_ACL_Exception($sError);
			}

			foreach($aResourcesAllow as $aResource) {
				 if(!is_array($aResource)) {
						$sError = sprintf('Single resource on resources list for action %s in controller %s must be an array', $sAction, $sController);

						throw new Rapide_Controller_Front_Plugin_ACL_Exception($sError);
				 }

				 if($oACL->isAllowed($aResource)) {
						return $oToken;
				 }
			}
		}
		else {
			$oUser = new Rapide_User;
			if($oUser->isAuthenticated())
				return $oToken;
		}

		return new Rapide_Dispatcher_Token($oConfig->get('Controller', 'error', 'controller'), $oConfig->get('Controller', 'error', 'action', '403'));
	}
}

?>